package com.ecommerce.service.impl;

import com.alibaba.fastjson.JSON;
import com.ecommerce.account.AddressInfo;
import com.ecommerce.common.TableId;
import com.ecommerce.dao.EcommerceAddressDao;
import com.ecommerce.entity.EcommerceAddress;
import com.ecommerce.filter.AccessContext;
import com.ecommerce.service.AddressService;
import com.ecommerce.vo.LoginUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class AddressServiceImpl implements AddressService {

    private final EcommerceAddressDao ecommerceAddressDao;

    public AddressServiceImpl(EcommerceAddressDao ecommerceAddressDao) {
        this.ecommerceAddressDao = ecommerceAddressDao;
    }

    /**
     * 存储多个地址信息
     */
    @Override
    public TableId createAddressInfo(AddressInfo addressInfo) {

        // 不能直接从参数中直接获取用户的 id 信息，因为可更改
        LoginUserInfo loginUserInfo = AccessContext.getLoginUserInfo();

        // 将传递的参数转换成实体对象
        List<EcommerceAddress> ecommerceAddresses = addressInfo.getAddressItems().stream()
                .map(a -> EcommerceAddress.to(loginUserInfo.getId(), a))
                .collect(Collectors.toList());

        // 保存到数据表并把返回记录的id给调用方
        List<EcommerceAddress> savedRecords = ecommerceAddressDao.saveAll(ecommerceAddresses);
        List<Long> ids = savedRecords.stream().map(EcommerceAddress::getId).collect(Collectors.toList());
        log.info("create address info: [{}], [{}]", loginUserInfo.getId(), JSON.toJSONString(ids));

        return new TableId(ids.stream().map(TableId.Id::new).collect(Collectors.toList()));
    }

    /**
     * 获取当前用户的地址信息
     */
    @Override
    public AddressInfo getCurrentAddressInfo() {

        LoginUserInfo loginUserInfo = AccessContext.getLoginUserInfo();

        // 根据 userId 查询到用户的地址信息，在实现转换
        List<EcommerceAddress> ecommerceAddresses = ecommerceAddressDao.findAllByUserId(loginUserInfo.getId());
        List<AddressInfo.AddressItem> addressItems = ecommerceAddresses.stream()
                .map(a -> a.toAddressItem()).collect(Collectors.toList());

        return new AddressInfo(loginUserInfo.getId(), addressItems);
    }

    /**
     * 根据id获取地址信息
     */
    @Override
    public AddressInfo getAddressInfoById(Long id) {

        // 根据 Id 查询到用户的地址信息，在实现转换
        EcommerceAddress ecommerceAddress = ecommerceAddressDao.findById(id).orElse(null);
        if (ecommerceAddress == null) {
            throw new RuntimeException("address is not exist");
        }

        return new AddressInfo(id, Collections.singletonList(ecommerceAddress.toAddressItem()));
    }

    /**
     * 根据TableId 查询AddressInfo
     */
    @Override
    public AddressInfo getAddressInfoByTableId(TableId tableId) {

        List<Long> ids = tableId.getIds().stream().map(TableId.Id:: getId).collect(Collectors.toList());
        log.info("get address info by table id", JSON.toJSONString(ids));

        List<EcommerceAddress> ecommerceAddresses = ecommerceAddressDao.findAllById(ids);
        if (CollectionUtils.isEmpty(ecommerceAddresses)) {
            return new AddressInfo(-1L, Collections.emptyList());
        }
        List<AddressInfo.AddressItem> addressItems = ecommerceAddresses.stream()
                .map(EcommerceAddress::toAddressItem)
                .collect(Collectors.toList());

        return new AddressInfo(ecommerceAddresses.get(0).getUserId(), addressItems);
    }

}
